from django.shortcuts import render, redirect, HttpResponse
from web import models
from django.http import JsonResponse
import datetime
from django_redis import get_redis_connection
import json
from utils.encrypt import uid
from utils.alipay import AliPay
from utils.alipay_link import alipay_link
from django.conf import settings
from utils.pagination import Pagination


# 主页


def index(request):
    return render(request, 'index.html')


def price(request):
    """套餐"""
    policy_list = models.CommodityPrices.objects.filter(category=2)
    return render(request, 'price.html', {"policy_list": policy_list})


def payment(request, policy_id):
    """支付页面"""
    policy_object = models.CommodityPrices.objects.filter(id=policy_id, category=2).first()
    if not policy_object:
        return redirect("websass:price")
    # 要购买的数量
    number = request.GET.get("number", "")
    if not number or not number.isdecimal():
        return redirect("websass:price")
    number = int(number)
    if number < 1:
        return redirect("websass:price")
    # 计算原价
    origin_price = number * policy_object.price

    # 之前购买过套餐
    total_day = number * 365
    _object = None
    if request.tracer.price_policy.category == 2:
        # 找到之前订单：总支付费用，开始`结束时间、剩余天数 = 抵扣的前
        _object = models.Transaction.objects.filter(t_user=request.tracer.user, t_status=2).order_by('-id').first()
        total_timedelta = _object.t_end - _object.t_start
        # 剩余的天数
        balance_timedelta = _object.t_end - datetime.datetime.now()
        # 把购买的时间和剩余的时间相加起来

        if total_timedelta.days == balance_timedelta.days:
            total_day = total_day + (balance_timedelta.days - 1)
        else:
            total_day = total_day + balance_timedelta.days

    context = {
        'policy_id': policy_id,
        'number': number,
        'origin_price': origin_price,
        'total_day': total_day,
    }
    conn = get_redis_connection()
    key = "payment_{}".format(request.tracer.user.mobile_phone)
    conn.set(key, json.dumps(context), ex=60 * 30)

    context['policy_object'] = policy_object
    context['transaction'] = _object
    return render(request, 'payment.html', context)


"""
def pay(request):
    conn = get_redis_connection()
    key = "payment_{}".format(request.tracer.user.mobile_phone)
    context_string = conn.get(key)
    if not context_string:
        return redirect("websass:price")
    context = json.loads(context_string.decode('utf-8'))
    # 1、生成数据库上传交易记录（待支付的状态）等支付成功之后更新订单状态
    uid_str = uid(request.tracer.user.mobile_phone)
    total_price = context['total_price']
    models.Transaction.objects.create(
        t_status=1,
        t_order=uid_str,
        t_user=request.tracer.user,
        t_price_id=context['policy_id'],  # 价格策略的id
        t_number=context['number'],
        t_pay=total_price
    )
    # 2、 跳转到支付宝支付界面
    params = {
        'app_id': "2021000116686471",
        'method': 'alipay.trade.page.pay',
        'format': 'JSON',
        'return_url': "http://127.0.0.1:8000/login",
        'notify_url': "http://127.0.0.1:8000/login",
        'charset': 'utf-8',
        'sign_type': 'RSA2',
        'timestamp': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        'version': '1.0',
        'biz_content': json.dumps({
            'out_trade_no': uid_str,
            'product_code': 'FAST_INSTANT_TRADE_PAY',
            'total_amount': total_price,
            'subject': "tracer payment"
        }, separators=(',', ':'))
    }

    # 获取待签名的字符串
    unsigned_string = "&".join(["{0}={1}".format(k, params[k]) for k in sorted(params)])

    # 签名 SHA256WithRSA(对应sign_type为RSA2)
    from Crypto.PublicKey import RSA
    from Crypto.Signature import PKCS1_v1_5
    from Crypto.Hash import SHA256
    from base64 import decodebytes, encodebytes

    # SHA256WithRSA + 应用私钥 对待签名的字符串 进行签名
    private_key = RSA.importKey(open("pay_files/应用私钥2048.txt").read())
    signer = PKCS1_v1_5.new(private_key)
    signature = signer.sign(SHA256.new(unsigned_string.encode('utf-8')))

    # 对签名之后的执行进行base64 编码，转换为字符串
    sign_string = encodebytes(signature).decode("utf8").replace('\n', '')

    # 把生成的签名赋值给sign参数，拼接到请求参数中。

    from urllib.parse import quote_plus
    result = "&".join(["{0}={1}".format(k, quote_plus(params[k])) for k in sorted(params)])
    result = result + "&sign=" + quote_plus(sign_string)

    gateway = "https://openapi.alipaydev.com/gateway.do"
    ali_pay_url = "{}?{}".format(gateway, result)
    return redirect(ali_pay_url)
"""


def pay(request, policy_id):
    conn = get_redis_connection()
    key = 'payment_{}'.format(request.tracer.user.mobile_phone)
    context_string = conn.get(key)
    if not context_string:
        return redirect('websass:price')
    context = json.loads(context_string.decode('utf-8'))

    # 1. 数据库中生成交易记录（待支付）
    #     等支付成功之后，我们需要把订单的状态更新为已支付、开始&结束时间
    order_id = uid(request.tracer.user.mobile_phone)
    total_price = context['origin_price']
    title = models.CommodityPrices.objects.filter(id=policy_id, category=2).first()

    models.Transaction.objects.create(
        t_status=1,
        t_order=order_id,
        t_user=request.tracer.user,
        t_price_id=context['policy_id'],  # 价格策略的id
        t_number=context['number'],
        t_pay=total_price
    )
    # 生成支付链接
    title = title.title + "商品"
    alipay_link_url = alipay_link(order_id, title, total_price)
    # ali_pay = AliPay(
    #     appid=settings.ALI_APPID,
    #     app_notify_url=settings.ALI_NOTIFY_URL,
    #     return_url=settings.ALI_RETURN_URL,
    #     app_private_key_path=settings.ALI_PRI_KEY_PATH,
    #     alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    # )
    # query_params = ali_pay.direct_pay(
    #     subject=,  # 商品简单描述
    #     out_trade_no=order_id,  # 商户订单号
    #     total_amount=total_price
    # )
    # pay_url = "{}?{}".format(settings.ALI_GATEWAY, query_params)
    return redirect(alipay_link_url)


def pay_notify(request):
    ali_pay = AliPay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url=settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRI_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    )
    if request.method == 'GET':
        params = request.GET.dict()
        sign = params.pop('sign', None)
        status = ali_pay.verify(params, sign)
        if status:
            current_datetime = datetime.datetime.now()
            # 把数据库里面的状态修改一下啊
            out_trade_no = params['out_trade_no']
            _object_list = models.Transaction.objects.filter(t_order=out_trade_no)
            _object = _object_list.first()

            _object.t_status = 2
            _object.t_start = current_datetime
            _object.t_end = current_datetime + datetime.timedelta(days=365 % _object.t_number)
            _object.save()
            order_list = models.Transaction.objects.filter(t_user=request.tracer.user)

            return render(request, 'trade_order.html', {'order_list': order_list})
        return HttpResponse('订单异常')
    else:
        # 当post请求的时候也要校验一下，get回来的数据在url里面直接就可以得到，而post是待在body里面
        from urllib.parse import parse_qs
        body_str = request.body.decode('utf-8')
        post_data = parse_qs(body_str)
        post_dict = {}
        for k, v in post_data.items():
            post_dict[k] = v[0]
        sign = post_dict.pop('sign', None)
        status = ali_pay.verify(post_dict, sign)
        if status:
            current_datetime = datetime.datetime.now()
            # 把数据库里面的状态修改一下啊
            out_trade_no = post_dict['out_trade_no']
            _object = models.Transaction.objects.filter(t_order=out_trade_no).first()

            _object.t_status = 2
            _object.t_start = current_datetime
            _object.t_end = current_datetime + datetime.timedelta(days=365 % _object.t_number)
            _object.save()
            return HttpResponse('success')
        return HttpResponse('error')


# 交易订单
def trade_order(request):
    if request.method == "GET":
        queryset = models.Transaction.objects.filter(t_user=request.tracer.user)
        # order_id = order_list.id
        # for order_id in order_list:
        #     print(order_id.id)
        # commodity_list = models.CommodityPrices.objects.filter(id=order_id)
        # context = {
        #     "order_list": order_list,
        #     "commodity_id": commodity_list
        # }
        page_object = Pagination(
            current_page=request.GET.get("page"),
            all_count=queryset.count(),
            base_url=request.path_info,
            query_params=request.GET,
            per_page=10
        )
        order_list = queryset[page_object.start:page_object.end]
        return render(request, 'trade_order.html', {'order_list': order_list, 'page_html': page_object.page_html()})


def trade_pay(request, policy_id):
    order = models.Transaction.objects.filter(id=policy_id).first()
    trade_id = order.t_order
    title = order.t_price.title + "商品"
    t_price = order.t_pay

    url = alipay_link(trade_id, title, t_price)
    return redirect(url)


def delete_order(request):
    order_id = request.GET.get("fid")
    models.Transaction.objects.filter(id=order_id, t_user=request.tracer.user).delete()
    return JsonResponse({"status": True})
